/*
 * Coding by Zhonghua. from 18-9-30 上午10:02.
 */

package vip.inode.demo.opusaudiodemo

import android.Manifest
import android.content.pm.PackageManager
import android.media.AudioManager
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import vip.inode.demo.opusaudiodemo.presenter.DecodeOpusPresenter
import vip.inode.demo.opusaudiodemo.utils.OpusPlayTask
import vip.inode.demo.opusaudiodemo.utils.OpusRecorderTask
import vip.inode.demo.opusaudiodemo.utils.Uilts
import java.io.File

class MainActivity : AppCompatActivity(), View.OnClickListener, OpusPlayTask.OnOpusPlayListener {
    private val TAG = javaClass.simpleName
    val APP_PATH: String = Environment.getExternalStorageDirectory().toString() + File.separator + "opusaudiodemo" + File.separator
    val APP_RECORDER_FILE_PATH: String = APP_PATH + "recorder_file" + File.separator

    private lateinit var recorderBtn: Button
    private lateinit var playBtn: Button
    private lateinit var playPcmBtn: Button
    private lateinit var test_opus_to_pcm_btn: Button


    private var recorderFilePath: String = APP_RECORDER_FILE_PATH + "recorder.ops"
    private var recorderPcmFilePath: String = APP_RECORDER_FILE_PATH + "recorder.pcm"
    private var recorderDecodedPcmFilePath: String = APP_RECORDER_FILE_PATH + "recorderDecoded.pcm"//解码后的PCM文件

    private var opusPlayTask: OpusPlayTask? = null
    private var opusRecorderTask: OpusRecorderTask? = null
    private lateinit var audioManager: AudioManager

    private val permissionRequestCode = 10

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        audioManager = getSystemService(AudioManager::class.java)
        initView()
        initData()

        MANAGE_EXTERNAL_STORAGE()
    }

    private fun initData() {
        recorderBtn.setOnClickListener(this)
        playBtn.setOnClickListener(this)
        playPcmBtn.setOnClickListener(this)
        test_opus_to_pcm_btn.setOnClickListener(this)
    }

    private fun initView() {
        recorderBtn = findViewById(R.id.recorder_btn)
        playBtn = findViewById(R.id.play_btn)
        playPcmBtn = findViewById(R.id.play_pcm_btn)
        test_opus_to_pcm_btn = findViewById(R.id.test_opus_to_pcm_btn)
    }

    override fun onClick(v: View) {
        when (v.id) {
            R.id.recorder_btn -> {
                if (opusRecorderTask == null) {
                    startRecorder()
                } else {
                    stopRecorder()
                }
            }
            R.id.play_btn -> {
                if (opusPlayTask == null) {
                    startPlay()
                } else {
                    stopPlay()
                }
            }
            R.id.play_pcm_btn -> {
                if (opusPlayTask == null) {
                    startPcmPlay()
                } else {
                    stopPlay()
                }
            }
            R.id.test_opus_to_pcm_btn -> {
                Thread {
                    Uilts.testOpusFileDecoder()
                }.start()

            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            permissionRequestCode -> {
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    startRecorder()
                } else {
                    toast(getString(R.string.permission_denied))
                }
            }
        }
    }

    private fun startRecorder() {
        if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_DENIED) {
            toast(getString(R.string.record_permission_denied))
            requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE), permissionRequestCode)
            return
        }
        if (opusRecorderTask != null) {
            toast(getString(R.string.play_error))
            return
        }
        recorderBtn.setText(R.string.stop_record)
        playPcmBtn.isEnabled = false
        playBtn.isEnabled = false

        opusRecorderTask = OpusRecorderTask(recorderFilePath, recorderPcmFilePath)
        Thread(opusRecorderTask).start()
    }

    private fun stopRecorder() {
        recorderBtn.setText(R.string.start_record)
        playPcmBtn.isEnabled = true
        playBtn.isEnabled = true
        if (opusRecorderTask != null) {
            opusRecorderTask!!.stop()
            opusRecorderTask = null
        }
    }

    private fun startPlay() {
        if (!File(recorderFilePath).exists() || opusPlayTask != null) {
            toast(getString(R.string.play_opus_error))
            return
        }
        recorderBtn.isEnabled = false
        playPcmBtn.isEnabled = false
        playBtn.setText(R.string.stop_opus)
        opusPlayTask = OpusPlayTask(audioManager, recorderFilePath, recorderDecodedPcmFilePath)
        opusPlayTask!!.onOpusPlayListener = this
        Thread(opusPlayTask).start()
    }

    private fun startPcmPlay() {
        if (!File(recorderPcmFilePath).exists() || opusPlayTask != null) {
            toast(getString(R.string.play_pcm_error))
            return
        }
        recorderBtn.isEnabled = false
        playBtn.isEnabled = false
        playPcmBtn.setText(R.string.stop_pcm)
        opusPlayTask = OpusPlayTask(audioManager, recorderPcmFilePath, null, true)
        opusPlayTask!!.onOpusPlayListener = this
        Thread(opusPlayTask).start()
    }

    private fun stopPlay() {
        playBtn.setText(R.string.play_opus_and_save_pcm)
        playPcmBtn.setText(R.string.play_pcm)
        playPcmBtn.isEnabled = true
        playBtn.isEnabled = true
        recorderBtn.isEnabled = true
        if (opusPlayTask != null) {
            opusPlayTask!!.stop()
            opusPlayTask = null
        }
    }

    override fun onCompere() {
        runOnUiThread {
            playBtn.setText(R.string.play_opus_and_save_pcm)
            playPcmBtn.setText(R.string.play_pcm)
            playPcmBtn.isEnabled = true
            playBtn.isEnabled = true
            recorderBtn.isEnabled = true
        }
        if (opusPlayTask != null) {
            opusPlayTask = null
        }
    }

    fun log(msg: String) {
        Log.d(TAG, msg)
    }

    private var toast: Toast? = null
    private fun toast(msg: String) {
        if (toast != null) {
            toast!!.cancel()
            toast = null
        }
        toast = Toast.makeText(this, msg, Toast.LENGTH_LONG)
        toast!!.show()
    }

    private fun MANAGE_EXTERNAL_STORAGE(){
        XXPermissions.with(this)
            // 申请单个权限
            .permission(Permission.MANAGE_EXTERNAL_STORAGE)
            // 设置权限请求拦截器（局部设置）
            //.interceptor(new PermissionInterceptor())
            // 设置不触发错误检测机制（局部设置）
            //.unchecked()
            .request(object : OnPermissionCallback {

                override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
                    if (!allGranted) {
                        toast("获取部分权限成功，但部分权限未正常授予")
                        return
                    }
                    toast("获取权限成功")
                }

                override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) {
                    if (doNotAskAgain) {
                        toast("被永久拒绝授权，请手动授予权限")
                        // 如果是被永久拒绝就跳转到应用权限系统设置页面
                    } else {
                        toast("获取权限失败")
                    }
                }
            })
    }

}
